//
//  PageFlowMenuTableViewCellBase.m
//  MKUITestApp
//
//  Created by 苏尚进 on 2020/10/6.
//  Copyright © 2020 moon. All rights reserved.
//

#import "PageFlowMenuTableViewCellBase.h"
#import "MenuCollectionViewCell_OnePage.h"

@interface TestPageFlowLayoutButton : MKUIFlowLayoutButton

@end
@implementation TestPageFlowLayoutButton
- (id)initWithTitle:(NSString *)title{
    if (self=[self init]) {
        self.titleLabel.font = [UIFont systemFontOfSize:14];
        [self setTitle:title forState:UIControlStateNormal];
        [self setTitleColor:[UIColor systemBlueColor] forState:UIControlStateNormal];
        self.minHitSize = CGSizeMake(30, 50);
        self.layer.borderColor = [UIColor systemGrayColor].CGColor;
        self.layer.borderWidth = 1;
        self.layer.cornerRadius = 3;
    }
    return self;
}
@end

@interface PageFlowMenuTableViewCellBase(){

}

@end
@interface MKUICollectionView_PageFlowMenuTableViewCellBase : MKUICollectionView

@end
@implementation MKUICollectionView_PageFlowMenuTableViewCellBase

- (void)setContentOffset:(CGPoint)contentOffset{
    NSLog(@"setContentOffset,from:%@,to:%@",NSStringFromCGPoint(self.contentOffset),NSStringFromCGPoint(contentOffset));
    [super setContentOffset:contentOffset];
}

@end
@implementation PageFlowMenuTableViewCellBase
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
    if (self=[super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
        self.myContentView = [[UIView alloc] init];
        self.myContentView.clipsToBounds = YES;
        self.myContentView.layer.cornerRadius = 5;
        self.myContentView.layer.borderColor = [UIColor systemGrayColor].CGColor;
        self.myContentView.layer.borderWidth = 1;
        [self.contentView addSubview:self.myContentView];
        //
        self.toolbarView = [[UIView alloc] init];
        [self.contentView addSubview:self.toolbarView];
        {
            self.refreshButton = [[TestPageFlowLayoutButton alloc] initWithTitle:@"Refresh"];
            [self.refreshButton addTarget:self action:@selector(onRefreshButton:) forControlEvents:UIControlEventTouchUpInside];
            [self.toolbarView addSubview:self.refreshButton];

            self.addButton = [[TestPageFlowLayoutButton alloc] initWithTitle:@"Add"];
            [self.addButton addTarget:self action:@selector(onAddButton:) forControlEvents:UIControlEventTouchUpInside];
            [self.toolbarView addSubview:self.addButton];

            self.removeButton = [[TestPageFlowLayoutButton alloc] initWithTitle:@"Remove"];
            [self.removeButton setTitleColor:[UIColor systemRedColor] forState:UIControlStateNormal];
            [self.removeButton addTarget:self action:@selector(onRemoveButton:) forControlEvents:UIControlEventTouchUpInside];
            [self.toolbarView addSubview:self.removeButton];


            self.scrollPreButton = [[TestPageFlowLayoutButton alloc] initWithTitle:@"Pre"];
            [self.scrollPreButton addTarget:self action:@selector(onScrollPreButton:) forControlEvents:UIControlEventTouchUpInside];
            [self.toolbarView addSubview:self.scrollPreButton];

            self.scrollNextButton = [[TestPageFlowLayoutButton alloc] initWithTitle:@"Next"];
            [self.scrollNextButton addTarget:self action:@selector(onScrollNextButton:) forControlEvents:UIControlEventTouchUpInside];
            [self.toolbarView addSubview:self.scrollNextButton];
            
            self.autoScrollButton = [[TestPageFlowLayoutButton alloc] initWithTitle:@"Auto"];
            [self.autoScrollButton setTitle:@"Stop" forState:UIControlStateSelected];
            [self.autoScrollButton addTarget:self action:@selector(onAutoScrollButton:) forControlEvents:UIControlEventTouchUpInside];
            [self.toolbarView addSubview:self.autoScrollButton];
            
            self.playButton = [[TestPageFlowLayoutButton alloc] initWithTitle:@"动画"];
            [self.playButton addTarget:self action:@selector(onPlayButton:) forControlEvents:UIControlEventTouchUpInside];
            [self.toolbarView addSubview:self.playButton];
            
            self.toolbarFlowLayoutConstraint = [[MKUIFlowLayoutConstraint alloc] initWithItems:self.toolbarView.subviews constraintParam:(MKUIFlowLayoutConstraintParam_H_C_L) contentInsets:UIEdgeInsetsZero interitemSpacing:10];
        }
        //
        self.pageFlowLayout = [[self.class.pageFlowLayoutClass alloc]
                               init];
        self.collectionView = [[MKUICollectionView_PageFlowMenuTableViewCellBase alloc] initWithFrame:CGRectZero collectionViewLayout:self.pageFlowLayout];
        self.collectionView.layer.borderColor = [UIColor lightGrayColor].CGColor;
        self.collectionView.layer.borderWidth = 1;
        self.collectionView.decelerationRate = [self defalutUIScrollViewDecelerationRate];
        self.collectionView.contentInset = UIEdgeInsetsMake(0, 30, 0, 30);
        [self.myContentView addSubview:self.collectionView];
        //
        self.pageControl = [[TestUIPageControl_3 alloc] init];
        [self.myContentView addSubview:self.pageControl];
        //
        MKUILayoutConstraintItemWrapper *w1 = [MKUILayoutConstraintItemWrapper wrapItem:self.toolbarView sizeThatFitsBlock:^CGSize(MKUILayoutConstraintItemWrapper * _Nonnull wrapper, CGSize size, BOOL resizeItems) {
            return CGSizeMake(size.width, 44);
        }];
        self.flowLayoutConstraint = [[MKUIFlowLayoutConstraint alloc] initWithItems:@[w1,[self myContentLayoutConstraint]] constraintParam:(MKUIFlowLayoutConstraintParam_V_T_C) contentInsets:MKUIEdgeInsetsMakeSameEdge(10) interitemSpacing:5];
        //
        self.lineView = [[UIView alloc] init];
        self.lineView.backgroundColor = [UIColor systemRedColor];
        [self.myContentView addSubview:self.lineView];
        //
        self.selectionStyle = UITableViewCellSelectionStyleNone;
        
        self.contentView.backgroundColor = [UIColor mk_colorWithLight:[UIColor whiteColor]];
        self.collectionView.backgroundColor = [UIColor mk_colorWithLight:[UIColor whiteColor]];
    }
    return self;
}
- (id<MKUILayoutConstraintItemProtocol>)myContentLayoutConstraint{
    @MK_WEAKIFY(self);
    MKUILayoutConstraintItemWrapper *w2 = [MKUILayoutConstraintItemWrapper wrapItem:self.myContentView sizeThatFitsBlock:^CGSize(MKUILayoutConstraintItemWrapper * _Nonnull wrapper, CGSize size, BOOL resizeItems) {
        @MK_NORMALIZE(self);
        CGSize s = [self sizeMyContentViewThatFits:size];
        return s;
    }];
    return w2;
}
- (void)layoutToolbar{
    CGRect bounds = self.toolbarView.bounds;
    self.toolbarFlowLayoutConstraint.bounds = bounds;
    [self.toolbarFlowLayoutConstraint layoutItemsWithResizeItems:YES];
}
- (void)customLayoutSubviews{
    [super customLayoutSubviews];
//    NSLog(@"layoutcell:%p,%@,change:%@",self,@(self.cellModel.indexPathInModel.row),@(self.isCellModelChanged));
    CGRect bounds = self.contentView.bounds;
    self.flowLayoutConstraint.bounds = bounds;
    [self.flowLayoutConstraint layoutItemsWithResizeItems:YES];
    //
    {
        [self layoutToolbar];
    }
    [self layoutMyContentView];
    {
        if(self.pageFlowLayout&&self.pageFlowLayout.pagingEnabled){
            MKCGAxis X = self.pageFlowLayout.scrollAxis;
            CGRect f1 = self.collectionView.frame;
            MKCGRectSetLength(&f1, X, 2);
            MKCGRectSetMin(&f1, X, MKCGRectGetMin(f1, X)+MKCGRectGetLength(self.collectionView.frame, X)*self.pageFlowLayout.pagingBoundsPositionForCollectionView);
            self.lineView.frame = f1;
        }
    }
    //
    
}
- (void)dealloc{
    
}
- (void)layoutMyContentView{
    
}
- (CGSize)customSizeThatFits:(CGSize)size{
    CGSize sizeFits = [self.flowLayoutConstraint sizeThatFits:size resizeItems:YES];
    return sizeFits;
}
- (void)customReloadCellModel{
    [super customReloadCellModel];
//    NSLog(@"cell:%p,%@,isChange:%@",self,@(self.cellModel.indexPathInModel.row),@(self.isCellModelChanged));
    self.lineView.hidden = !(self.pageFlowLayout&&self.pageFlowLayout.pagingEnabled);
    [self.lineView.superview bringSubviewToFront:self.lineView];
    
    self.pageFlowLayout.itemAlignment = [self.cellModel mk_integerForKeyPath:@"itemAlignment" otherwise:MKCGRectAlignmentMid];
    self.collectionView.decelerationRate = [self.cellModel mk_doubleForKeyPath:@"decelerationRate" otherwise:[self defalutUIScrollViewDecelerationRate]];
    self.pageFlowLayout.pagingEnabled = [self.cellModel mk_boolForKeyPath:@"pagingEnabled" otherwise:YES];
    [self reloadData];
}
- (void)tableView:(UITableView *)tableView willDisplayCellModel:(__kindof MKUITableViewCellModel *)cellModel{
    if(self.isCellModelChanged){
        NSIndexPath *p = [self.cellModel mk_valueForKeyPath:@"indexPathAtPagingCell" otherwise:[NSIndexPath indexPathForRow:0 inSection:0]];
        if(p){
            [self.pageFlowLayout setIndexPathAtPagingCell:p animated:NO];
        }
        [self reloadPageControl];
    }
    [self setupAutoScrolling];
}

- (CGSize)sizeMyContentViewThatFits:(CGSize)size{
    return size;
}
+ (Class)pageFlowLayoutClass{
    return [MKUICollectionViewPageFlowLayout class];
}
- (void)reloadData{
    [self.collectionView.model removeAllSectionModels];
    NSArray<Menu *> *menus = self.cellModel.modelValue;
    @MK_WEAKIFY(self);
    for (Menu *menu in menus) {
        MKUICollectionViewCellModel *cm = [MKUICollectionViewCellModel modelWithValue:menu];
        cm.whenClick = ^(__kindof MKUICollectionViewCellModel * _Nonnull cellModel) {
            @MK_NORMALIZE(self);
            if(self.pageFlowLayout.pagingEnabled){
                [self.pageFlowLayout setIndexPathAtPagingCell:cellModel.indexPathInModel animated:YES];
            }else{
                [self.collectionView scrollToItemAtIndexPath:cellModel.indexPathInModel atScrollPosition:(UICollectionViewScrollPositionNone) animated:YES];
            }
        };
        cm.cellClass = [self.class menuCellClass];
        [self.collectionView.model addCellModel:cm];
    }
    [self.collectionView.model reloadCollectionViewData];
    [self reloadPageControl];
}
- (void)reloadPageControl{
    NSArray<Menu *> *menus = self.cellModel.modelValue;
    self.pageControl.numberOfPages = menus.count;
    NSIndexPath *indexPathAtPagingCell = self.pageFlowLayout.indexPathAtPagingCell;
    if(indexPathAtPagingCell){
        self.pageControl.currentPage = indexPathAtPagingCell.item;
    }else{
        if(!menus.count){
            self.pageControl.currentPage = 0;
        }
    }
}
- (void)onRefreshButton:(id)sender{
    self.cellModel.needReloadCell = YES;
    [self.cellModel refreshWithAnimated:NO];
}
- (void)onAddButton:(id)sender{
    NSIndexPath *p = self.pageFlowLayout.indexPathAtPagingCell;
    if(p){
        MKUICollectionViewCellModel *cm = [self.collectionView.model cellModelAtIndexPath:p];
        Menu *menu = [Menu random];
        NSMutableArray<Menu *> *menus = [NSMutableArray arrayWithArray:self.cellModel.modelValue];
        [menus insertObject:menu atIndex:p.item];
        self.cellModel.modelValue = menus;
        
        MKUICollectionViewCellModel *newCM = [MKUICollectionViewCellModel modelWithValue:menu];
        newCM.cellClass = cm.cellClass;
        [self.collectionView.model insertCellModel:newCM atIndexPath:p animated:YES completion:^(BOOL finished) {
            self.cellModel.needReloadCell = YES;
            [self.cellModel refreshWithAnimated:YES];
        }];
    }
}
- (void)onScrollPreButton:(id)sender{
    NSInteger step = [self.cellModel mk_integerForKeyPath:@"step" otherwise:1];
    [self.pageFlowLayout setIndexPathAtPagingCellWithDistance:-1*step animated:YES];
}
- (void)onScrollNextButton:(id)sender{
    NSInteger step = [self.cellModel mk_integerForKeyPath:@"step" otherwise:1];
    [self.pageFlowLayout setIndexPathAtPagingCellWithDistance:step animated:YES];
}
- (void)onAutoScrollButton:(id)sender{
    BOOL autoScroll = !self.autoScrollButton.selected;
    self.cellModel[@"autoScroll"] = @(autoScroll);
    [self setupAutoScrolling];
    [self layoutToolbar];
}
- (void)onPlayButton:(id)sender{
    CGRect bounds = self.contentView.bounds;
    CGPoint originOffset = self.collectionView.contentOffset;
    CGPoint offset = originOffset;
    offset.x += bounds.size.width/4;
    MKUIAnimation *animation = [[MKUIAnimation alloc] init];
    animation.duration = 0.5;
    MKUIAnimationEasingBounce *easing = [MKUIAnimationEasingBounce functionWithBounceCount:2];
    animation.easingFunction = easing.In;
    CGPoint offset1 = self.collectionView.contentOffset;
    CGPoint offset2 = offset;
    animation.animationsBlock = ^(CGFloat progress) {
        self.collectionView.contentOffset = MKCGPointInterpolate(offset1, offset2, progress);
    };
    animation.completionBlock = ^(BOOL finished) {
        self.collectionView.contentOffset = originOffset;
    };
    [animation beginAnimation];
}
- (void)setupAutoScrolling{
    BOOL autoScroll = [self.cellModel mk_boolForKeyPath:@"autoScroll" otherwise:NO];
    NSInteger autoScrollDistance = [self.cellModel mk_integerForKeyPath:@"autoScrollDistance" otherwise:1];
    self.autoScrollButton.selected = autoScroll;
    [self layoutToolbar];
    if(autoScroll){
        [self.pageFlowLayout startAutoScrollingWithDistance:autoScrollDistance duration:3];
    }else{
        [self.pageFlowLayout stopAutoScrolling];
    }
}
+ (Class)menuCellClass{
    return [MenuCollectionViewCell_OnePage class];
}
- (void)onRemoveButton:(id)sender{
    NSIndexPath *p = self.pageFlowLayout.indexPathAtPagingCell;
    if(p){
        MKUICollectionViewCellModel *cm = [self.collectionView.model cellModelAtIndexPath:p];
        
        NSMutableArray<Menu *> *menus = [NSMutableArray arrayWithArray:self.cellModel.modelValue];
        [menus removeObjectAtIndex:p.item];
        self.cellModel.modelValue = menus;
        
        [cm removeCellModelWithAnimated:YES completion:^(BOOL finished) {
            self.cellModel.needReloadCell = YES;
            [self.cellModel refreshWithAnimated:YES];
        }];
    }
}
- (UIEdgeInsets)cellInsets{
    return UIEdgeInsetsZero;
}
- (UIScrollViewDecelerationRate)defalutUIScrollViewDecelerationRate{
    return UIScrollViewDecelerationRateFast;
}
- (void)tableView:(UITableView *)tableView didEndDisplayingCellModel:(__kindof MKUITableViewCellModel *)cellModel{
    [self.pageFlowLayout stopAutoScrolling];
}
#pragma mark - delegate:UICollectionViewDelegate,MKUICollectionViewDelegatePageFlowLayout
- (void)collectionView:(UICollectionView *)collectionView pageFlowLayout:(MKUICollectionViewPageFlowLayout *)collectionViewLayout didScrollToPagingCell:(NSIndexPath *)indexPathAtPagingCell{
    self.cellModel[@"indexPathAtPagingCell"] = indexPathAtPagingCell;
    [self reloadPageControl];
}
- (CGSize)collectionView:(UICollectionView *)collectionView pageFlowLayout:(MKUICollectionViewPageFlowLayout *)collectionViewLayout itemSizeForItemAtIndexPath:(NSIndexPath *)indexPath{
    CGRect bounds = collectionView.bounds;
    UIEdgeInsets insets = [self sectionInsets];
    MKCGAxis X = self.pageFlowLayout.scrollAxis;
    MKCGAxis Y = MKCGAxisReverse(X);
    CGSize size = bounds.size;
    MKCGSizeSetLength(&size, Y, MKCGSizeGetLength(size, Y)-MKUIEdgeInsetsGetEdgeSum(insets, Y));
    UIEdgeInsets cellInsets = [self cellInsets];
    MKCGSizeSetLength(&size, X, MKCGSizeGetLength(size, X)-MKUIEdgeInsetsGetEdgeSum(cellInsets, X));
    return size;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    NSIndexPath *toIndexPath;
    CGFloat progress = [self.pageFlowLayout scrollProgressWithContentOffset:scrollView.contentOffset toPagingCell:&toIndexPath];
    [self.pageControl scrollToPageIndex:toIndexPath.item progress:progress];
}
- (UIEdgeInsets)sectionInsets{
    UIEdgeInsets insets = MKUIEdgeInsetsMakeSameEdge(10);
    if(self.collectionView.model.numberOfCells>1&&self.pageFlowLayout.enableCycleScroll){
        MKCGAxis X = self.pageFlowLayout.scrollAxis;
        MKUIEdgeInsetsSetEdge(&insets, X, MKUIEdgeInsetsMax,self.pageFlowLayout.interitemSpacing/2);
        MKUIEdgeInsetsSetEdge(&insets, X, MKUIEdgeInsetsMin,self.pageFlowLayout.interitemSpacing/2);
    }
    return insets;
}
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView pageFlowLayout:(MKUICollectionViewPageFlowLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{
    return [self sectionInsets];
}
@end
